#include "stdafx.h"
#include "play_mgr.h"
#include "media_play_thread.h"
#include "ISocketInterface.h"
#include "corlor_convert.h"

list<boost::tuple<string, int> > CPlayMgr::_ip_addr_list;

CPlayMgr::CPlayMgr(ILiveEvent* event_)
:_pEvent(event_)
, _corlor_convert(NULL)
{
    _pMediaPlayThd = new CMediaPlayThread(_pEvent);
    _corlor_convert = new CCorlorConvert;
}

CPlayMgr::~CPlayMgr(void)
{
    if (_pSessionMgr.get())
    {
        _pSessionMgr.reset();
    }
    if (_pMediaPlayThd)
    {
        delete _pMediaPlayThd;
    }
    if (_corlor_convert)
    {
        delete _corlor_convert;
        _corlor_convert = NULL;
    }
}

int CPlayMgr::add_sev_ip_info(const unsigned long ip_, const int port_, 
    const short type_, const short my_type_)
{
    if (0 == ip_ || port_ <= 0)
    {
        return -1;
    }
    unsigned long ip_tmp = ntohl(ip_);
    struct in_addr in;
    memcpy(&in, &ip_tmp, sizeof(ip_));
    char *ip_str_ = inet_ntoa(in);
    if (NULL == ip_str_)
    {
        BOOST_WARNING << "inet_ntoa failed. from : " << ip_;
        return -1;
    }
    if (type_ == my_type_)
    {
        _ip_addr_list.push_front(boost::make_tuple(string(ip_str_), port_));
    } else
    {
        _ip_addr_list.push_back(boost::make_tuple(string(ip_str_), port_));
    }
    return 0;
}

int CPlayMgr::del_sev_ip_info(const unsigned long ip_)
{
    int ret(-1);
    if (0 == ip_ || _ip_addr_list.empty())
    {
        return ret;
    }
    struct in_addr in;
    memcpy(&in, &ip_, sizeof(ip_));
    char *ip_str_ = inet_ntoa(in);
    if (NULL == ip_str_)
    {
        BOOST_WARNING << "inet_ntoa failed. from : " << ip_;
        return ret;
    }
    BOOST_AUTO(itor, _ip_addr_list.begin());
    while (itor != _ip_addr_list.end())
    {
        if (0 == (*itor).get<0>().compare(ip_str_))
        {
            _ip_addr_list.erase(itor++);
            ret = 0;
            continue;
        }
        ++itor;
    }
    return ret;
}

void CPlayMgr::clear_sev_ip_info()
{
    _ip_addr_list.clear();
}

int CPlayMgr::Login(const unsigned int uid_, const unsigned int room_id_, NETPROTO proto_ /*= _eHttp*/)
{
    if (_ip_addr_list.empty())
    {
        BOOST_WARNING << "CPlayMgr::Login uid:" << uid_ << "; room id:" << room_id_ << 
            "; failed, sev ip list is null.";
        return -1;
    }
    if (_pSessionMgr.get())
    {
        _pSessionMgr.reset();
    }
    if (_eHttp == proto_)
    {
        _pSessionMgr = boost::shared_ptr<ISocketInterface>(GetHttpInterface(_pEvent, uid_, room_id_));
    }else if (_eUdp == proto_)
    {
        _pSessionMgr = boost::shared_ptr<ISocketInterface>(GetUdpSockInterface(_pEvent, uid_, room_id_));
    }else if (_eRtmp == proto_)
    {
    }
    if (!_pSessionMgr.get())
    {
        return -1;
    }
    if (_pMediaPlayThd)
    {
        _pMediaPlayThd->set_play_flag(1);
    }
    _pSessionMgr->set_video_cb(boost::bind(&CMediaPlayThread::on_recv_video_packet, _pMediaPlayThd, _1));
    _pSessionMgr->set_audio_cb(boost::bind(&CMediaPlayThread::on_recv_audio_packet, _pMediaPlayThd, _1));
    BOOST_AUTO(ip_addr, _ip_addr_list.front());
    _ip_addr_list.pop_front();
    _ip_addr_list.push_back(ip_addr);
    return _pSessionMgr->login(ip_addr.get<0>().c_str(), ip_addr.get<1>(), 0);
}

int CPlayMgr::Logout( )
{
    if (_pMediaPlayThd)
    {
        _pMediaPlayThd->set_play_flag(0);
    }
    if (_pSessionMgr.get())
    {
        _pSessionMgr->set_event(NULL);
        _pSessionMgr->set_video_cb(NULL);
        _pSessionMgr->set_audio_cb(NULL);
        _pSessionMgr.reset();
    }
    return 0;
}

bool CPlayMgr::is_logined()
{
    if (_pSessionMgr.get())
    {
        return _pSessionMgr->is_login();
    } else
    {
        return false;
    }
}

void CPlayMgr::save_bmp(const char* file_name_, const int len_)
{
    if (_pMediaPlayThd)
    {
        _pMediaPlayThd->save_bmp(file_name_, len_);
    }
}

int CPlayMgr::swscale_rgb24_img(unsigned char* src_data_, int src_width_, int src_height_, int src_format_, 
    unsigned char* dst_data_, int dst_width_, int dst_height_, int dst_format_)
{
    if (!src_data_ || !dst_data_ || !_corlor_convert)
    {
        return -1;
    }
    return _corlor_convert->img_convert(src_data_, src_width_, src_height_, (AVPixelFormat)src_format_,
        dst_data_, dst_width_, dst_height_, (AVPixelFormat)dst_format_, false);
}

